/**
 * @brief 文件传输模块
 * @version 1.0
 * @author 宋炜
 */

#pragma once
#include <algorithm>

#include "designM/bridge.hpp"
#include "misc.hpp"
#include "designM/absFactory.hpp"
#include "details/ftp.hpp"
#include "url.hpp"
#include "details/aliOSS.hpp"
#include "details/httpFile.hpp"
#include "details/fileSvrItfc.hpp"

namespace wheels
{
namespace fileClient {

    using ftpClient = dm::bridge<iFileService , curlFtp >;
    using aliOSSClient = dm::bridge< iFileService , aliOSS >;
    using httpClient = dm::bridge< iFileService , curlHttp >;

    class fileClient : public dm::abstractFactory< curlHttp , curlFtp , aliOSS >
    {
    public:
        /**
         * @brief 根据URL中的协议内容初始化下载接口。
         * @param url[ I ]， 文件来源
         * @return 成功操作返回
         */
        std::shared_ptr< iFileService > newClient( const std::string& url , long ovt )
        {
            URL url__( url );
            std::string p = url__.Protocol();
            std::transform( p.begin() , p.end() , p.begin() , ::tolower );

            switch( hash_(p.c_str()) ){
            case "http"_hash:
            case "https"_hash:{
                auto ret = makeShared<0>();
                ret->overtime( ovt );
                return std::dynamic_pointer_cast<iFileService>(ret);
            }
            case "ftp"_hash:
            case "ftps"_hash:{
                auto ret = makeShared<1>();
                ret->overtime( ovt );
                return std::dynamic_pointer_cast<iFileService>(ret);;
            }
            default:
                if( p.empty() ){
                    auto ret = makeShared<2>( "" );
                    ret->overtime( ovt );
                    return std::dynamic_pointer_cast<iFileService>(ret);;
                }
                break;
            }

            return {};
        }
        iFileService * newClientNaked( const std::string& url , long ovt )
        {
            URL url__( url );
            std::string p = url__.Protocol();
            std::transform( p.begin() , p.end() , p.begin() , ::tolower );

            switch( hash_(p.c_str()) ){
            case "http"_hash:
            case "https"_hash:{
                auto ret = create<0>();
                ret->overtime( ovt );
                return ret;
            }
            case "ftp"_hash:
            case "ftps"_hash:{
                auto ret = create<1>();
                ret->overtime( ovt );
                return ret;
            }
            default:
                if( p.empty() ){
                    auto ret = create<2>( "" );
                    ret->overtime( ovt );
                    return ret;
                }
                break;
            }

            return {};
        }
    };
}
}
